
#include "GwGraphics_global.h"
#include "gwrectangle.h"
#include "gwscene.h"
#include <QBuffer>
#include <QDebug>
#include <QFileDialog>
#include <QFileInfo>
#include <QKeyEvent>
#include <QXmlStreamWriter>

GwScene::GwScene(QObject *parent):QGraphicsScene(parent)
{

}

GwScene::~GwScene()
{
    qDebug()<<"before exit scene";
    if(background!=NULL)
        delete this->background;
    qDebug()<<"after exit scene";
}



//void GwScene::addGWRect(gwRectangle *rect)
//{
//    this->lst_gw_rects.append(rect);
//    this->addItem(rect);
//}

//void GwScene::removeGWRect(gwRectangle *rect)
//{
//    this->lst_gw_rects.removeAll(rect);
//    this->removeItem(rect);
//}

void GwScene::setBackgroundPic(QString filename)
{
    QPixmap pic(this->width(),this->height());
    if(filename=="")
    {
        pic.fill(Qt::white);
        qDebug()<<"pic:white";
    }
    else pic.load(filename);
    backgroundFile=filename;
    pic=pic.scaled(this->width(),this->height(),Qt::IgnoreAspectRatio,
                   Qt::SmoothTransformation);
    if(background==NULL)
        background=this->addPixmap(pic);
    else
        background->setPixmap(pic);
    background->setZValue(-1);
}

void GwScene::addItem(QGraphicsItem *item)
{
    size_t tp=typeid(*item).hash_code();
    if(tp==typeid(GwRectangle).hash_code())
    {
        GwRectangle *index=(GwRectangle *)item;
        this->lst_gw_rects.append(index);
    }
    else if(tp==typeid(GwDetector).hash_code())
    {
        GwDetector *index=(GwDetector *)item;
        this->lst_gw_detector.append(index);
    }
    else if(tp==typeid(GwText).hash_code())
    {
        GwText *index=(GwText *)item;
        this->lst_gw_txts.append(index);
    }
    QGraphicsScene::addItem(item);
}

void GwScene::removeItem(QGraphicsItem *item)
{
    size_t tp=typeid(*item).hash_code();
    if(tp==typeid(GwRectangle).hash_code())
    {
        GwRectangle *index=(GwRectangle *)item;
        this->lst_gw_rects.removeAll(index);
    }
    else if(tp==typeid(GwDetector).hash_code())
    {
        GwDetector *index=(GwDetector *)item;
        this->lst_gw_detector.removeAll(index);
    }
    else if(tp==typeid(GwText).hash_code())
    {
        GwText *index=(GwText *)item;
        this->lst_gw_txts.removeAll(index);
    }
    QGraphicsScene::removeItem(item);
}

QList<GwDetector *> GwScene::getDetectorList()
{
    return this->lst_gw_detector;
}

QList<GwRectangle *> GwScene::getRoomList()
{
    return this->lst_gw_rects;
}

QString GwScene::getSceneProjectFile()
{
    return ProFile;
}

void GwScene::setParentScene(GwScene *parent)
{
    this->parentScene=parent;
}

GwScene *GwScene::getParentScene()
{
    return this->parentScene;
}

StateInfo GwScene::getRoomStateInfo()
{
    return this->dev_cnt;
}


QByteArray GwScene::packGwDetector()
{
    QList<GwDetector> list_detector;
    QByteArray tmp_array;
    QBuffer buffer(&tmp_array);
    QDataStream out(&buffer);
    buffer.open(QIODevice::ReadWrite);
    foreach (GwDetector *index, this->lst_gw_detector) {
        list_detector<<(*index);
    }
    out<<list_detector;
    buffer.close();
    list_detector.clear();
    return tmp_array;
}


QByteArray GwScene::packGWRect()
{
    QList<GwRectangle> list_rects;
    QByteArray tmp_array;
    QBuffer buffer(&tmp_array);
    QDataStream out(&buffer);
    buffer.open(QIODevice::ReadWrite);
    foreach (GwRectangle *index, this->lst_gw_rects) {
        list_rects<<(*index);
    }
    out<<list_rects;
    buffer.close();
    list_rects.clear();
    return tmp_array;
}

QByteArray GwScene::packGWText()
{
    QList<GwText> list_txt;
    QByteArray tmp_array;
    QBuffer buffer(&tmp_array);
    QDataStream out(&buffer);
    buffer.open(QIODevice::ReadWrite);
    foreach (GwText *index, this->lst_gw_txts) {
        list_txt<<(*index);
    }
    out<<list_txt;
    buffer.close();
    list_txt.clear();
    return tmp_array;
}

QByteArray GwScene::packGWScene()
{
    QByteArray tmp_array;
    QBuffer buffer(&tmp_array);
    QDataStream out(&buffer);
    buffer.open(QIODevice::ReadWrite);
    out<<this->width()<<this->height()<<this->backgroundFile;
    buffer.close();
    return tmp_array;
}

void GwScene::unpackGWScene(QByteArray data,bool isconfig)
{
    QBuffer buffer(&data);
    buffer.open(QIODevice::ReadOnly);
    QDataStream in(&buffer);
    qreal width,height;
    QString file;
    in>>width>>height>>file;
    this->setSceneRect(0,0,width,height);
    this->setBackgroundPic(file);
    this->backgroundFile=file;
    buffer.close();
}

void GwScene::unpackGWRect(QByteArray data, bool isconfig)
{
    QList<GwRectangle> list_rects;
    list_rects.clear();
    GwRectangle index;GwRectangle *rect;
    QBuffer buffer(&data);
    buffer.open(QIODevice::ReadOnly);
    QDataStream in(&buffer);
    qDeleteAll(this->lst_gw_rects);
    this->lst_gw_rects.clear();
    in>>list_rects;
    foreach (index, list_rects) {
        rect=new GwRectangle(index);
        this->addItem(rect);
        if(isconfig)
            rect->setConfig();
    }
    buffer.close();
}

void GwScene::unpackGWDetector(QByteArray data,bool isconfig)
{
    QList<GwDetector> list_detector;
    list_detector.clear();
    GwDetector index;GwDetector *det;
    QBuffer buffer(&data);
    buffer.open(QIODevice::ReadOnly);
    QDataStream in(&buffer);
    qDeleteAll(this->lst_gw_detector);
    this->lst_gw_detector.clear();
    in>>list_detector;
    foreach (index, list_detector) {
        det=new GwDetector(index);
        this->addItem(det);
        if(isconfig)
            det->setConfig();
    }
    buffer.close();
}

void GwScene::unpackGWText(QByteArray data, bool isconfig)
{
    QList<GwText> list_text;
    list_text.clear();
    GwText index;GwText *txt;
    QBuffer buffer(&data);
    buffer.open(QIODevice::ReadOnly);
    QDataStream in(&buffer);
    qDeleteAll(this->lst_gw_txts);
    this->lst_gw_txts.clear();
    in>>list_text;
    foreach (index, list_text) {
        txt=new GwText(index);
        this->addItem(txt);
        if(isconfig)
            txt->setConfig();
    }
    buffer.close();
}

void GwScene::save()
{
    QString filename;
    filename=QFileDialog::getSaveFileName(nullptr,tr("项目另存为"),"",tr("GOWIN Project (*.gwprj2)"));
    QFile file(filename);
    if(!file.open(QFile::WriteOnly|QFile::Truncate)) //可以用QIODevice，Truncate表示清空原来的内容
        return;
    QXmlStreamWriter stream(&file);
    stream.setAutoFormatting(true);
    stream.writeStartDocument();
    stream.writeStartElement("ViewScene");
    stream.writeTextElement("ViewGWScene", packGWScene().toHex());
    stream.writeTextElement("ViewGWRectItem", packGWRect().toHex());
    stream.writeTextElement("ViewGWDetectorItem", packGwDetector().toHex());
    stream.writeTextElement("ViewGWTextItem", packGWText().toHex());
    stream.writeEndElement();
    stream.writeEndDocument();
    file.close();
}



void GwScene::load(bool isconfig)
{
    QString filename;
    filename=QFileDialog::getOpenFileName(nullptr,tr("打开工程"),"",tr("GOWIN Project (*.gwprj2)"));
    this->ProFile=filename;
    this->load(filename,isconfig);
}

void GwScene::load(QString filename,bool isconfig)
{
    QByteArray tmp;
    QXmlStreamReader reader;
    QFile file(filename);
    this->ProFile=filename;
    if(file.open(QFile::ReadOnly))
    {
        if(lst_gw_rects.count()>0)
        {
            qDeleteAll(lst_gw_rects);
            lst_gw_rects.clear();
        }
        if(lst_gw_detector.count()>0)
        {
            qDeleteAll(lst_gw_detector);
            lst_gw_detector.clear();
        }
        if(lst_gw_txts.count()>0)
        {
            qDeleteAll(lst_gw_txts);
            lst_gw_txts.clear();
        }
        reader.setDevice(&file);
        while(!reader.atEnd()) {
            if(reader.isStartElement())
            {
                if(reader.name()=="ViewScene")
                {
                    while(!reader.atEnd())
                    {
                        if(reader.name()=="ViewGWScene")
                        {
                            this->unpackGWScene(QByteArray::fromHex(reader.readElementText().toLatin1()),isconfig);
                        }
                        if(reader.name()=="ViewGWRectItem")
                        {
                            this->unpackGWRect(QByteArray::fromHex(reader.readElementText().toLatin1()),isconfig);
                        }
                        if(reader.name()=="ViewGWDetectorItem")
                        {
                            this->unpackGWDetector(QByteArray::fromHex(reader.readElementText().toLatin1()),isconfig);
                        }
                        if(reader.name()=="ViewGWTextItem")
                        {
                            this->unpackGWText(QByteArray::fromHex(reader.readElementText().toLatin1()),isconfig);
                        }
                        reader.readNext();
                    }
                }
                else
                    reader.readNext();
            }
            else
                reader.readNext();
        }
        // 如果读取过程中出现错误，那么输出错误信息
        if (reader.hasError()) {
            qDebug() << "error: " << reader.errorString();
        }
    }
    file.close();
}

void GwScene::stateChanged(GraphicsState info)
{
    GwDetector *dev;
    dev_cnt.stateLOCnt=0;
    dev_cnt.stateHICnt=0;
    dev_cnt.stateOKCnt=0;
    dev_cnt.stateDISCnt=0;
    foreach(dev,this->lst_gw_detector)
    {
        qDebug()<<dev->getState();
        switch(dev->getState())
        {
        case GState_OK:
        {
            dev_cnt.stateOKCnt++;
            break;
        }
        case GState_LO:
        {
            dev_cnt.stateLOCnt++;
            break;
        }
        case GState_HI:
        {
            dev_cnt.stateHICnt++;
            break;
        }
        case GState_DIS:
        {
            dev_cnt.stateDISCnt++;
            break;
        }
        }
    }
    qDebug()<<"ok:"<<dev_cnt.stateOKCnt<<"lo:"<<dev_cnt.stateLOCnt<<"hi:"<<dev_cnt.stateHICnt<<"dis:"<<dev_cnt.stateDISCnt;

}


void GwScene::keyPressEvent(QKeyEvent *event)
{
    switch(event->key())
    {
    case Qt::Key_Delete:
    {
        this->removeItem(this->selectedItems()[0]);
        break;
    }
    }

    QGraphicsScene::keyPressEvent(event);
}


